module app.controller.admin.ArticleController;

import hunt.framework;
import app.model.Article;
import app.repository.ArticleRepository;
import app.response.ResultMsg3;
import app.response.ResultMsg;
import app.utils.RespCodeEnun;
import app.utils.RespCodeEnun;
import std.json;
import app.middleware.CheckIdValidity;

class ArticleController : Controller
{
    mixin MakeController;

    /**
    * 文章列表
    */
    @Action Response list()
    {
        import std.conv : to;

        string keywords = request.get("keywords", "");
        int page = to!int(request.get("page", "1"));
        int perPage = to!int(request.get("perPage", "7"));

        ArticleRepository articleRepository = new ArticleRepository();
        ResultMsg3 resultMsg = new ResultMsg3();

        try
        {
            auto artData = articleRepository.findArticlesByPagination(page, perPage, keywords);
            auto articles = artData.getContent();
            long total = artData.getTotalElements();

            JSONValue[] items;
            foreach (article; articles)
            {
                JSONValue item;
                item["id"] = article.id;
                item["cid"] = article.cid;
                item["title"] = article.title;
                item["desc"] = article.desc;
                items ~= item;
            }
            resultMsg.code = RespCodeEnun.SUCCESS;
            resultMsg.msg = "success";
            resultMsg.total = total;
            resultMsg.data["data"] = items;
        }
        catch (Exception e)
        {
            this.response.setStatus(500);
            resultMsg.code = RespCodeEnun.ERROR;
            resultMsg.msg = "系统错误";
        }
        return new JsonResponse(resultMsg);
    }

    /**
    * 删除文章
    */
    @Middleware(CheckIdValidity.stringof)  // id参数检查中间件
    @Action Response del(long id)
    {
        ArticleRepository articleRepository = new ArticleRepository();

        // 查找操作对象
        Article article = articleRepository.findById(id);
        if (article is null)
        {
            this.response.setStatus(404);
            return new JsonResponse(new ResultMsg(RespCodeEnun.Not_Found, "操作对象不存在"));
        }

        try
        {
            articleRepository.remove(article);
            return new JsonResponse(new ResultMsg(RespCodeEnun.SUCCESS, "操作成功"));
        }
        catch (Exception e)
        {
            this.response.setStatus(500);
            return new JsonResponse(new ResultMsg(RespCodeEnun.ERROR, "操作失败"));
        }

    }

    /**
    * 通过分类id获取文章列表
    */
    @Middleware(CheckIdValidity.stringof)  // id参数检查中间件
    @Action Response cateArtList(long id)
    {
        import app.repository.CategoryRepository;

        if (id <= 0)
        {
            this.response.setStatus(400);
            return new JsonResponse(new ResultMsg(RespCodeEnun.Bad_Request,
                    "错误的请求，请检查分类id"));
        }

        CategoryRepository cateRepository = new CategoryRepository();
        ResultMsg3 resultMsg = new ResultMsg3();

        auto articles = cateRepository.findArticsleByCateId(id);
        JSONValue[] items;
        foreach (article; articles)
        {
            JSONValue item;
            item["id"] = article.id;
            item["cid"] = article.cid;
            item["title"] = article.title;
            item["desc"] = article.desc;
            items ~= item;
        }
        resultMsg.code = RespCodeEnun.SUCCESS;
        resultMsg.msg = "success";
        resultMsg.total = articles.length;
        resultMsg.data["data"] = items;

        return new JsonResponse(resultMsg);
    }

    /**
    * 文章详情
    * @Parameters    id   long   文章id
    */
    @Middleware(CheckIdValidity.stringof)  // id参数检查中间件
    @Action Response detail(long id)
    {
        import std.random : choice;
        import std.string : tr;
        import std.datetime.systime : SysTime, unixTimeToStdTime;
        import app.utils.Const;

        ResultMsg resultMsg = new ResultMsg();
        ArticleRepository articleRepository = new ArticleRepository();

        Article article = articleRepository.findById(id);
        if (article is null)
        {
            this.response.setStatus(404);
            return new JsonResponse(new ResultMsg(RespCodeEnun.Not_Found, "文章未找到"));
        }

        JSONValue item;
        item["id"] = article.id;
        item["cid"] = article.cid;
        item["title"] = article.title;
        item["desc"] = article.desc;
        item["content"] = article.content;
        resultMsg.code = RespCodeEnun.SUCCESS;
        resultMsg.msg = "success";
        resultMsg.data["data"] = item;

        return new JsonResponse(resultMsg);
    }

    /**
    * 添加文章
    */
    @Action Response add()
    {
        import std.datetime.systime : Clock;

        JSONValue addJson = request.json();
        string title = addJson["title"].str;
        long cid = addJson["cid"].integer;
        string desc = addJson["desc"].str;
        string content = addJson["content"].str;

        Article artcicle = new Article();
        artcicle.title = title;
        artcicle.cid = cid;
        artcicle.desc = desc;
        artcicle.content = content;
        artcicle.createdAt = Clock.currTime().toUnixTime();
        artcicle.updatedAt = Clock.currTime().toUnixTime();

        // 字段有效性验证
        auto result = artcicle.valid();
        if (result.isValid() == false)
        {
            import std.format : format;

            string errmsg = "";
            foreach (key, message; result.messages())
            {
                auto em = format("%s: %s ;\t", key, message);
                errmsg ~= em;
            }
            return new JsonResponse(new ResultMsg(RespCodeEnun.Bad_Request, errmsg));
        }

        ArticleRepository artRepository = new ArticleRepository();
        try
        {
            // 插入
            artRepository.insert(artcicle);
            return new JsonResponse(new ResultMsg(RespCodeEnun.SUCCESS, "添加文章成功"));
        }
        catch (Exception e)
        {
            return new JsonResponse(new ResultMsg(RespCodeEnun.ERROR, "操作失败"));
        }
    }

    /**
    * 更新文章信息
    */
    @Middleware(CheckIdValidity.stringof)  // id参数检查中间件
    @Action Response update(long id)
    {
        ArticleRepository artRepository = new ArticleRepository();

        // 接收提交过来的json值
        JSONValue editJson = request.json();
        long cid = editJson["cid"].integer;
        string title = editJson["title"].str;
        string desc = editJson["desc"].str;
        string content = editJson["content"].str;

        // 查找操作对象
        Article article = artRepository.findById(id);
        if (article is null)
        {
            this.response.setStatus(404);
            return new JsonResponse(new ResultMsg(RespCodeEnun.Not_Found, "操作对象不存在"));
        }

        // 更新
        import std.datetime.systime : Clock;

        article.cid = cid;
        article.title = title;
        article.desc = desc;
        article.content = content;
        article.updatedAt = Clock.currTime().toUnixTime();
        try
        {
            // 更新
            artRepository.save(article);
            return new JsonResponse(new ResultMsg(RespCodeEnun.SUCCESS, "更新成功"));
        }
        catch (Exception e)
        {
            this.response.setStatus(500);
            return new JsonResponse(new ResultMsg(RespCodeEnun.ERROR, "更新失败"));
        }
    }
}
